package com.clementheliou.cheliou.business.functional.photo.impl;

import static com.clementheliou.cheliou.business.util.properties.CHeliouBusinessProperties.FUNCTIONAL_PHOTO_LARGE_HEIGHT;
import static com.clementheliou.cheliou.business.util.properties.CHeliouBusinessProperties.FUNCTIONAL_PHOTO_LARGE_WIDTH;
import static com.clementheliou.cheliou.business.util.properties.CHeliouBusinessProperties.FUNCTIONAL_PHOTO_MEDIUM_HEIGHT;
import static com.clementheliou.cheliou.business.util.properties.CHeliouBusinessProperties.FUNCTIONAL_PHOTO_MEDIUM_WIDTH;

import java.awt.Dimension;

import org.apache.commons.configuration.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.clementheliou.cheliou.business.functional.photo.PhotoFunctionalService;
import com.clementheliou.cheliou.dal.model.photo.Photo;

/**
 * Default implementation of the {@link PhotoFunctionalService} interface.
 * <p>
 * Due to the {@link Transactional} annotation and the value of its
 * <i>readOnly</i> attribute, all methods are called in a transaction that will
 * be rollbacked in the end. This behavior can be overriden at the method level,
 * more particularly if you need to perform an insert, update or delete action.
 * </p>
 * 
 * @author Clément HELIOU (clement.heliou@gmail.com)
 * @see {@link PhotoFunctionalService};
 * @see {@link Service};
 * @see {@link Transactional}.
 * @since 1.0
 */
@Service
@Transactional(readOnly = true)
public class PhotoDefaultFunctionalService implements PhotoFunctionalService {

	/**
	 * Logger for this class.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(PhotoDefaultFunctionalService.class);

	/**
	 * Properties of the business layer.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Autowired
	@Qualifier("businessProperties")
	private Configuration businessProperties;

	/**
	 * <i>{@inheritDoc}</i>
	 * <p>
	 * There are 3 available sizes: small, medium and large. The following rules
	 * are applied to determinate which one should be used:
	 * <ul>
	 * <li>If the screen size is greater or equals to 1920x1200 px, the large
	 * one is used;</li>
	 * <li>Else, if the screen size is greater or equals to 1440x900px, the
	 * medium one is used;</li>
	 * <li>Otherwise, the small one is used.</li>
	 * </ul>
	 * </p>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	public String getPhotoPathToUse(Dimension currentScreenSize, Photo photo) {
		final int height = currentScreenSize.height, width = currentScreenSize.width;
		LOGGER.debug("Get the photo path for the screen size {}x{} px.", width, height);

		if (height >= businessProperties.getInt(FUNCTIONAL_PHOTO_LARGE_HEIGHT) && width >= businessProperties.getInt(FUNCTIONAL_PHOTO_LARGE_WIDTH)) {
			LOGGER.debug("Large size available!");
			return photo.getLargePath();
		}

		if (height >= businessProperties.getInt(FUNCTIONAL_PHOTO_MEDIUM_HEIGHT) && width >= businessProperties.getInt(FUNCTIONAL_PHOTO_MEDIUM_WIDTH)) {
			LOGGER.debug("Medium size available!");
			return photo.getMediumPath();
		}

		LOGGER.debug("Sorry, only the small size is available!");
		return photo.getSmallPath();
	}
}
